package de.ret_world.openrpgstudio.mapeditor.engine;

import com.artemis.Entity;
import de.ret_world.openrpgstudio.editor.Project;
import de.ret_world.openrpgstudio.editor.script.Point;
import de.ret_world.openrpgstudio.editor.script.ScriptObject;
import de.ret_world.openrpgstudio.engine.artemis.components.Location;
import de.ret_world.openrpgstudio.engine.artemis.components.LuaComponent;
import de.ret_world.openrpgstudio.engine.artemis.components.SkinComponent;
import de.ret_world.openrpgstudio.engine.loading.LoadPlugin;
import de.ret_world.openrpgstudio.mapeditor.scripts.Layer;
import de.ret_world.openrpgstudio.mapeditor.scripts.TileMap;
import de.ret_world.openrpgstudio.mapeditor.scripts.TileSet;
import java.awt.Rectangle;
import java.util.HashMap;
import org.apache.log4j.Logger;
import org.jrabbit.base.data.loading.FileLoader;
import org.jrabbit.base.graphics.image.Image;
import org.jrabbit.base.graphics.skins.Skin;
import org.jrabbit.base.graphics.skins.image.SubImageSkin;
import org.jrabbit.base.managers.Resources;

/**
 * This initializes the TilemapWorlds for the game engine.
 *
 * @author Emu
 */
public class TilemapLoader extends LoadPlugin {

    private HashMap<TileSet, HashMap<Integer, Skin>> tiles = new HashMap<>();

    @Override
    public void load() {
        Logger.getLogger(TilemapLoader.class).info("Loading TileSets and TileMaps");

        for (ScriptObject so : Project.getInstance().getDatabase().getScriptMap(TileMap.TYPE).values()) {
            TileMap tilemap = (TileMap) so;

            Logger.getLogger(TilemapLoader.class).info("Loading TileMap: " + tilemap);

            int dx = (tilemap.getWidth() * tilemap.getTileWidth()) / 2;
            int dy = (tilemap.getHeight() * tilemap.getTileHeight()) / 2;

            for (Layer layer : tilemap.getLayers()) {
                if (layer.getType().equals(Layer.TYPE.TILE) && layer.getTileset() != null && layer.getTileset().getImage() != null) {
                    TileSet tileset = layer.getTileset();
                    Image img = new Image(tileset.getID(), new FileLoader(Project.getInstance().getFolder("root").resolve(tileset.getImage().getFile()).toFile()));
                    Resources.images().add(img);

                    HashMap<Integer, Skin> map = tiles.get(tileset);
                    if (map == null) {
                        Logger.getLogger(TilemapLoader.class).info("Loading TileSet: " + tileset);

                        map = new HashMap<>();
                        tiles.put(tileset, map);

                        for (int i = 0; i < tileset.getTilesPerColumn() * tileset.getTilesPerRow(); i++) {
                            if (tileset.getTiles().size() > i) {
                                Rectangle r = tileset.getTiles().get(i);
                                SubImageSkin simg = new SubImageSkin(tileset.getID(), r.x, r.y, r.width, r.height);

                                map.put(i, simg);
                            }
                        }
                    }

                    Logger.getLogger(TilemapLoader.class).info("Init Layer: " + layer);
                    for (Point p : layer.getPoints().keySet()) {
                        int tile = layer.getPoints().get(p);
                        if (map.containsKey(tile)) {
                            Entity e = entityWorld.createEntity();
                            e.addComponent(new SkinComponent(map.get(tile)));
                            float x = (p.getX() * tilemap.getTileWidth()) - (tilemap.getTileWidth() / 2);
                            float y = (p.getY() * tilemap.getTileHeight()) - (tilemap.getTileHeight() / 2);

                            e.addComponent(new Location(tilemap.getID(), layer.getID(), new Point(x, y)));
                            e.addComponent(new LuaComponent(tilemap));
                            e.setGroup(tilemap.getID() + "_Tiles");
                            e.refresh();
                        }
                    }
                }
            }
        }
    }
}
